
#include <stddef.h>
#include "GT20L16_IO.h"


static uint8_t GB_HZZF_len(uint8_t * hzStr) //获得GB汉字所占用的字节数
{
	uint8_t c1, c2;

	c1 = *hzStr++;
	if(c1 < 0x20) {
		return (0);
	}
	if(c1 < 0x80) {
		return (1);
	}
	c2 = *hzStr++;
	if((c1 == 0x81 && c2 >= 0x39) || (c1 == 0x82)) {
		return (4);
	}
	return (2);
}


static uint32_t GTAddress(uint8_t * HZ, uint8_t HZ_type) //获得汉字点阵的地址
{
	uint32_t address;
	uint8_t c1, c2, c3, c4;

	c1 = HZ[0];
	if(c1 < 0x80) //ASCII ,半角 
	{
		if(c1 < 0x20) {
			address = 0;
		}
		else {
			address = c1 - 0x20;
		}
		if(HZ_type == 8) {
			address = address * 16 + 0x18a400;
		}
		else if(HZ_type == 12) {
			address = address * 12 + 0x00;
		}
		else if(HZ_type == 16) {
			address = address * 8 + 0x00;
		}
		else if(HZ_type == 24) {
			address = address * 48 + 0x00;
		}
		else if(HZ_type == 32) {
			address = address * 64 + 0x00;
		}
	}
	else //chinese	for BG2312,GBK,GB18030,GB12345
	{
		c2 = HZ[1];

		//符号区,全角 846+96 = 1038
		if((c1 >= 0xA1 && c1 <= 0xAB && c2 >= 0xa1) || (c1 >= 0xa8 && c1 <= 0xa9 && c2 < 0xa1)) {
			if(c1 >= 0xA1 && c1 <= 0xAB && c2 >= 0xa1) //双字节字符1区 846
			{
				address = (c1 - 0xA1) * 94 + (c2 - 0xA1);
			}
			else //双字节字符5区 96
			{
				if(c2 > 0x7f) {
					c2--;
				}
				address = (c1 - 0xa8) * 96 + (c2 - 0x40) + 846;
			}
			if(HZ_type == 12) {
				return (address * 24 + 0x0000);
			}
			else if(HZ_type == 16) {
				return (address * 32 + 0xA7700);
			}
			else if(HZ_type == 24) {
				return (address * 72 + 0x00000);
			}
			else if(HZ_type == 32) {
				return (address * 128 + 0x00000);
			}
			else return (0x00);
		}

		//GBK双字节2区 6768
		else if(c1 >= 0xb0 && c1 <= 0xf7 && c2 >= 0xa1) {
			address = (c1 - 0xB0) * 94 + (c2 - 0xA1);
		}

		//GBK 双字节3区 6080
		else if(c1 < 0xa1 && c1 >= 0x81 && c2 >= 0x40) {
			if(c2 > 0x7f) {
				c2--;
			}
			address = (c1 - 0x81) * 190 + (c2 - 0x40) + 6768;
		}

		//GBK 双字节4区 8160
		else if(c1 >= 0xaa && c2 < 0xa1) {
			if(c2 > 0x7f) {
				c2--;
			}
			address = (c1 - 0xaa) * 96 + (c2 - 0x40) + 12848;
		}
		else if(c1 == 0x81 && c2 >= 0x39) //4//四字节区1
		{
			c3 = HZ[2];
			c4 = HZ[3];
			address = 21008 + (c3 - 0xEE) * 10 + c4 - 0x39;
		}
		else if(c1 == 0x82) //四字节区1
		{
			c3 = HZ[2];
			c4 = HZ[3];
			address = 21008 + 161 + (c2 - 0x30) * 1260 + (c3 - 0x81) * 10 + c4 - 0x30;
		}
		if(HZ_type == 12) {
			address = address * 24 + 0x0000 + 1038 * 24;
		}
		else if(HZ_type == 16) {
			address = address * 32 + 0xA7700 + 1038 * 32;
		}
		else if(HZ_type == 24) {
			address = address * 72 + 0x0000;
		}
		else if(HZ_type == 32) {
			address = address * 128 + 0x0000;
		}
		else return (0x00);
	}
	return address;
}


/*********************************************************************************************************
** Function name:			GTRead
** Descriptions:			GTRead
*********************************************************************************************************/
static uint32_t GT20L16_Read(uint32_t address)
{
	uint8_t buffer[2] = {
		0
	};
	uint32_t data;

	GT20L16_IO_Read(address, buffer, sizeof(buffer));
	data = buffer[0] *256 + buffer[1];
	return data;
}


/*********************************************************************************************************
** Function name:			getAddrFromUnicode
** Descriptions:			get .. address
*********************************************************************************************************/
uint32_t GT20L16_GetAddrFromUnicode(uint32_t unicode)
{
	if(unicode <= 45632) // char
	{
		uint32_t base = 0;
		uint32_t address;

		if(unicode >= 0x20 && unicode <= 0x7f) {
			address = 16 * (unicode - 0x20) +base;
		}
		else if(unicode >= 0xa0 && unicode <= 0xff) {
			address = 16 * (96 + unicode - 0xa0) +base;
		}
		else if(unicode >= 0x100 && unicode <= 0x17f) {
			address = 16 * (192 + unicode - 0x100) +base;
		}
		else if(unicode >= 0x1a0 && unicode <= 0x1cf) {
			address = 16 * (320 + unicode - 0x1a0) +base;
		}
		else if(unicode >= 0x1f0 && unicode <= 0x1ff) {
			address = 16 * (368 + unicode - 0x1f0) +base;
		}
		else if(unicode >= 0x210 && unicode <= 0x21f) {
			address = 16 * (384 + unicode - 0x210) +base;
		}
		else if(unicode >= 0x1ea0 && unicode <= 0x1eff) {
			address = 16 * (400 + unicode - 0x1ea0) +base;
		}
		else if(unicode >= 0x370 && unicode <= 0x3cf) {
			address = 16 * (496 + unicode - 0x370) +base;
		}
		else if(unicode >= 0x400 && unicode <= 0x45f) {
			address = 16 * (592 + unicode - 0x400) +base;
		}
		else if(unicode >= 0x490 && unicode <= 0x4ff) {
			address = 16 * (688 + unicode - 0x490) +base;
		}
		else if(unicode >= 0x590 && unicode <= 0x5ff) {
			address = 16 * (800 + unicode - 0x100) +base;
		}
		else if(unicode >= 0xe00 && unicode <= 0xe7f) {
			address = 16 * (912 + unicode - 0xe00) +base;
		}
		else address = base;
		return address;
	}
	else {
		uint32_t ZFAdd, HZAdd;
		uint8_t MSB, LSB;
		uint32_t ChineseTab;
		uint32_t data;
		uint32_t Add_Chinese;

		MSB = unicode >> 8;
		LSB = unicode;
		ZFAdd = 36224;
		HZAdd = 93452;
		ChineseTab = 87436;
		if(MSB >= 0xA1 && MSB <= 0xA5) //char area
		{
			if(MSB == 0xA1 && LSB >= 0xA1 && LSB <= 0xBF) {
				Add_Chinese = 32 * (LSB - 0xA1) +ZFAdd;
			}
			else if(MSB == 0xA3 && LSB >= 0xA1 && LSB <= 0xFE) {
				Add_Chinese = 32 * (31 + LSB - 0xA1) +ZFAdd;
			}
			else if(MSB == 0xA4 && LSB >= 0xA1 && LSB <= 0xF3) {
				Add_Chinese = 32 * (125 + LSB - 0xA1) +ZFAdd;
			}
			else if(MSB == 0xA5 && LSB >= 0xA1 && LSB <= 0xF6) {
				Add_Chinese = 32 * (208 + LSB - 0xA1) +ZFAdd;
			}
			else Add_Chinese = ZFAdd;
		}
		else if((MSB >= 0xB0 && MSB <= 0xD7) && (LSB >= 0xA1 && LSB <= 0xFE)) //chinese 5720
		{
			Add_Chinese = (MSB - 176) * 94 + (LSB - 161) + 1;
			Add_Chinese = Add_Chinese * 32 + HZAdd;
		}
		else if((MSB >= 0xD8 && MSB <= 0xF7) && (LSB >= 0xA1 && LSB <= 0xFE)) //chinese 5720~6763
		{
			Add_Chinese = (MSB - 0xD8) * 94 + (LSB - 0xA1);
			Add_Chinese = Add_Chinese * 2 + ChineseTab;
			data = GT20L16_Read(Add_Chinese);
			Add_Chinese = 32 * data + HZAdd;
		}
		return Add_Chinese;
	}
}


int GT20L1_GetMatrixGBK(uint32_t gbkCode, uint8_t * matrix)
{
	if(matrix == NULL) {
		return 0;
	}
	uint8_t size = 16;
	uint32_t address = 0;
	uint8_t code[4];

	memcpy(code, &gbkCode, sizeof(code));
	uint8_t len = GB_HZZF_len(code);

	if(len > 0) {
		if(len >= 2) { 
			//中文
			address = GTAddress(code, 16);
			size = 32;
		}
		else { 
			//ASCII
			address = GTAddress(code, 8);
		}
	}
	GT20L16_IO_Read(address, matrix, size);
	return size;
}


int GT20L1_GetMatrixUnicode(uint32_t uniCode, uint8_t * matrix)
{
	if(matrix == NULL) {
		return 0;
	}
	uint8_t size = (uniCode <= 45632) ? 16: 32;
	uint32_t address = GT20L16_GetAddrFromUnicode(uniCode);

	GT20L16_IO_Read(address, matrix, size);
	return size;
}


